package com.chat.login.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chat.common.common.constant.MessageConstant;
import com.chat.common.common.constant.RedisKeyConstant;
import com.chat.common.common.exception.RoutineException;
import com.chat.common.dto.AuthRequestDTO;
import com.chat.common.entity.User;
import com.chat.common.vo.R;
import com.chat.login.config.JwtProperties;
import com.chat.login.domain.dto.CheckMailDTO;
import com.chat.login.domain.vo.CaptchaVO;
import com.chat.login.domain.vo.EncryptEmailVO;
import com.chat.login.domain.vo.LoginUserVO;
import com.chat.login.service.AuthService;
import com.chat.login.service.CaptchaService;
import com.chat.login.service.IUserService;
import com.chat.login.utils.JwtTool;

import com.chat.login.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class AuthServiceImpl implements AuthService {

    //jwt工具
    @Autowired
    JwtTool jwtTool;
    //jwt配置
    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IUserService userService;

    @Autowired
    private CaptchaService captchaService;

    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public R validateToken(AuthRequestDTO authRequestDTO) {
        String token = authRequestDTO.getToken();
        Long ID = jwtTool.parseToken(token);
        String url = authRequestDTO.getUrl();
        if(antPathMatcher.match("**/admin/**", url)){
            if (redisUtil.hasKey(RedisKeyConstant.ADMIN_ACCOUNT_ForToken + ID)){
                log.info("管理员校验通过");
                return R.succeed();
            }
        } else {
            Long IDRedis = (Long) redisUtil.get(RedisKeyConstant.TOKEN_USER + token);
            if (IDRedis != null && IDRedis.equals(ID)){
                log.info("普通用户校验通过");
                return R.succeed();
            }
        }
        log.info("token校验失败");
        return R.failed("token校验失败");
    }

    @Override
    public R<LoginUserVO> refreshToken(String token) {
        Long userID = jwtTool.parseToken(token);
        Long userId = (Long) redisUtil.get(RedisKeyConstant.TOKEN_USER + token);
        //删除RedisKeyConstant.TOKEN_USER
        if (userId!=null && Objects.equals(userID, userId)){
            redisUtil.delete(RedisKeyConstant.TOKEN_USER + token);
        }
        String account = (String) redisUtil.get(RedisKeyConstant.TOKEN_ACCOUNT + token);
        if(account!=null && account.isEmpty()){
            redisUtil.delete(RedisKeyConstant.TOKEN_ACCOUNT + token);
            redisUtil.delete(RedisKeyConstant.USER_ACCOUNT_ForToken + account);
        }
        String newToken = jwtTool.createToken(userID,jwtProperties.getTokenTTL());
        //把token存入redis
        redisUtil.setEx(RedisKeyConstant.TOKEN_USER + newToken, userID, 12, TimeUnit.HOURS);
        //存用户登录信息
        redisUtil.setEx(RedisKeyConstant.USER_ACCOUNT_ForToken + account, newToken, 12, TimeUnit.HOURS);
        redisUtil.setEx(RedisKeyConstant.TOKEN_ACCOUNT + newToken, account, 12, TimeUnit.HOURS);
        return R.succeed(LoginUserVO.builder().token(newToken).build());
    }

    @Override
    public R getAccountOfMail(String account) {
        String email = userService.getMailOfAccount(account);
        int index = email.indexOf("@");
        if(index >= 1) {
            email= email.charAt(0) + "****" + email.substring(index);
        }
        EncryptEmailVO encryptEmailVO = new EncryptEmailVO(email);
        return R.succeed(encryptEmailVO);
    }

    @Override
    public R getAccountOfMail(User user) {
        return getR(user);
    }

    @NotNull
    private R getR(User user) {
        String email = user.getEmail();
        int index = email.indexOf("@");
        if(index >= 1) {
            email= email.charAt(0) + "****" + email.substring(index);
        }
        EncryptEmailVO encryptEmailVO = new EncryptEmailVO(email);
        return R.succeed(encryptEmailVO);
    }

    //TODO:目前先这样写如果要复用再想办法
    @Override
    public R checkMailAndAccount(CheckMailDTO checkMailDTO) {
        String email = userService.getMailOfAccount(checkMailDTO.getAccount());
        if(email.equals(checkMailDTO.getEmail())){
            CaptchaVO captchaVO = captchaService.sendTextMailMessage(email);
            return R.succeed(captchaVO);
        }else{
            throw new RoutineException("当前邮箱错误");
        }
    }

    //:TODO:这里应该是可以复用的
    @Override
    public R BooleanAccountState(String account) {
        User user = userService.getBaseMapper().selectOne(
                new LambdaQueryWrapper<User>()
                        .eq(User::getAccount, account)
        );
        if (user == null){
            //判断账号是否存在
            throw new RoutineException(MessageConstant.ACCOUNT_NOT_FOUND);
        } else if(user.getState().equals(1)){
            //判断账号是否被锁定
            throw new RoutineException("账号未被锁定");
        } else {
            return getR(user);
        }
    }
}
